use std::collections::HashMap;
use std::sync::Arc;
use std::sync::OnceLock;
use std::sync::RwLock;

use tklog::error;

use crate::session::session::Session;

#[derive(Clone, Debug)]
pub struct SessionManager {
    timeout: u64,
    sessions: Arc<RwLock<HashMap<String, Session>>>, //hashmap线程不安全, Arc 允许多线程同时访问, 但需要使用RwLock来保证线程安全
}

const DEFAULT_TIMEOUT: u64 = 1800; //默认时间为1800秒
const DEFAULT_SESSION_COUNT: usize = 1;

impl SessionManager {
    pub fn init(timeout: Option<u64>) -> Result<Self, Box<dyn std::error::Error>> {
        let timeout = timeout.unwrap_or(DEFAULT_TIMEOUT);
        let session_manager = SessionManager {
            timeout,
            sessions: Arc::new(RwLock::new(HashMap::with_capacity(DEFAULT_SESSION_COUNT))), //只需要管理员需要登陆
        };
        Ok(session_manager)
    }

    pub fn add_session(&mut self, id: String, session: Session) {
        self.sessions.write().unwrap().insert(id, session);
    }

    pub fn remove_session(&mut self, id: &str) {
        self.sessions.write().unwrap().remove(id);
    }

    pub fn is_session_exist(&self, id: &str) -> bool {
        self.sessions.read().unwrap().contains_key(id)
    }

    pub fn is_expired(&self, id: &str) -> bool {
        self.sessions
            .read()
            .unwrap()
            .get(id)
            .map_or(false, |session| session.is_expired(self.timeout))
    }
}
